package caramcraft;

import java.util.LinkedList;

import jnibwapi.JNIBWAPI;
import jnibwapi.model.Unit;
import jnibwapi.types.TechType;
import jnibwapi.types.WeaponType;
import math.geom2d.Vector2D;

/**
 * Created by Stefan Rudolph on 18.02.14.
 */
public class Marine extends SCUnit {
	private TechType stim = bwapi.getTechType(TechType.TechTypes.Stim_Packs
			.getID());
	private final int marineId;

	public Marine(Unit unit, JNIBWAPI bwapi) {
		super(unit, bwapi, bwapi
				.getWeaponType(WeaponType.WeaponTypes.Gauss_Rifle.getID()));
		marineId = 0;
	}

	public Marine(Unit unit, JNIBWAPI bwapi, LinkedList<SCUnit> myUnits,
			LinkedList<Unit> myBuildings, LinkedList<SCUnit> enemyUnits,
			LinkedList<Unit> enemyBuildings, int marineId) {
		super(unit, bwapi, bwapi
				.getWeaponType(WeaponType.WeaponTypes.Gauss_Rifle.getID()),
				myUnits, myBuildings, enemyUnits, enemyBuildings);
		this.marineId = marineId;
	}

	public void step(long frame) {
		if( isSleep(frame) )
			return;
		
		LinkedList<SCUnit> attackers = this.getAttackers();
		// run away if we're low on health!
		if( this.getHealthPercent() < 0.45 && attackers.size() > 0 )
		{
			Vector2D moveTo = seperate(attackers);
			move(getPosition().plus(moveTo));
			sleep(frame,2);
			return;
		}
		// continue attacking
		if( isAttacking() )
		{
			// use stim!
			if( !isStimmed() && this.getHealthPercent() > 0.4 )
			{
				this.stim();
				sleep(frame,2);
			}
			return;
		}
		// get our units
		LinkedList<Tank> tanks = new LinkedList<Tank>();
		int marines = 0;
		boolean isSieged = false;
		for( SCUnit u: myUnits)
		{
			if( u instanceof Tank )
			{
				Tank t = (Tank)u;
				tanks.add(t);
				isSieged |= t.isSieged();
			}
			if( u instanceof Marine )
				marines++;
		}
		// if tanks are sieged
		if( isSieged )
		{
			// attack enemy
			SCUnit enemy = this.getNearestEnemy();
			if( enemy != null )
			{
				attack(enemy.me);
				sleep(frame,2);
				return;
			}
		}
		// get middle point between tanks
		Vector2D moveTo = new Vector2D();
		for( Tank t: tanks )
			moveTo = moveTo.plus(t.getPosition());
		moveTo = new Vector2D( moveTo.x() / tanks.size(), moveTo.y() / tanks.size() );
		double radius = 100;
		if( tanks.size() == 2 )
			radius = Math.max(radius, tanks.getFirst().getPosition().minus(tanks.getLast().getPosition()).norm() );
		double winkel = 2 * Math.PI / marines;
		moveTo = moveTo.plus( new Vector2D(Math.cos(winkel*marineId)*radius, Math.sin(winkel*marineId)*radius) );
		moveTo = moveTo.plus(seperate(50));
		move(moveTo);
		sleep(frame,2);
		return;
	}

	public void stim() {
		bwapi.useTech(me.getID(), stim.getID());
	}
	
	public boolean isStimmed()
	{
		return me.isStimmed();
	}
	public int getStimTimer()
	{
		return me.getStimTimer();
	}
}
